#include "HFunctionTable.h"
//#include "HSymbolTable.h"
#include <cassert>

unsigned int HFunctionTable::ymr = 0U;

HFunctionTable::HFunctionTable()
{
	cact_type_t *pptype;
	// We only allow one global function table
	assert(++ymr == 1U);

	// Add built-in functions
	_funcs.resize(BUILTIN_NUM);
	// void print_int(int);
	_funcs[0U].funcid = "print_int";
	_funcs[0U].rettype = Btype::VOID;
	pptype = new cact_type_t;
	pptype->base_type = Btype::INT;
	pptype->is_const = false;
	_funcs[0U].paramtype.push_back(pptype);
	// void print_float(float);
	_funcs[1U].funcid = "print_float";
	_funcs[1U].rettype = Btype::VOID;
	pptype = new cact_type_t;
	pptype->base_type = Btype::FLOAT;
	pptype->is_const = false;
	_funcs[1U].paramtype.push_back(pptype);
	// void print_double(double);
	_funcs[2U].funcid = "print_double";
	_funcs[2U].rettype = Btype::VOID;
	pptype = new cact_type_t;
	pptype->base_type = Btype::DOUBLE;
	pptype->is_const = false;
	_funcs[2U].paramtype.push_back(pptype);
	// void print_bool(bool);
	_funcs[3U].funcid = "print_bool";
	_funcs[3U].rettype = Btype::VOID;
	pptype = new cact_type_t;
	pptype->base_type = Btype::BOOL;
	pptype->is_const = false;
	_funcs[3U].paramtype.push_back(pptype);
	// int get_int();
	_funcs[4U].funcid = "get_int";
	_funcs[4U].rettype = Btype::INT;
	// int get_float();
	_funcs[5U].funcid = "get_float";
	_funcs[5U].rettype = Btype::FLOAT;
	// int get_double();
	_funcs[6U].funcid = "get_double";
	_funcs[6U].rettype = Btype::DOUBLE;

	assert(_funcs.size() == BUILTIN_NUM);
}

/*
 * Add a function entry to the function table and return the index
 * of the new entry, or `SIZE_MAX` if it (the same name) already exists.
 */
size_t HFunctionTable::add_func(const std::string &id, Btype rtype,
		HSymbolTable *psymtb, const std::vector<const cact_type_t *> &paramtype)
{
	HFTEntry temp;
	size_t osz = _funcs.size();

	if (search_func(id) != SIZE_MAX)
		return SIZE_MAX;

	_funcs.resize(osz + 1U);
	_funcs.at(osz).funcid = id;
	_funcs.at(osz).rettype = rtype;
	_funcs.at(osz).paramtype = paramtype;
	_funcs.at(osz).psymtb = psymtb;
	return osz;
}

/*
 * Search a function according to its name and return index
 * of it or `SIZE_MAX` if not found.
 */
size_t HFunctionTable::search_func(const std::string &id) const
{
	for (size_t i = 0u; i < _funcs.size(); ++i)
		if (_funcs.at(i).funcid == id)
			return i;
	return SIZE_MAX;
}

HFunctionTable::~HFunctionTable()
{
	assert(--ymr == 0U);
}